SVG live editor on Scrapbox
parsererrorにエラー内容が入っている
2022-06-06
08:46:41 いい加減releaseしたい
code:svg
<svg xml="1.0">
<script>
scriptはrenderingされない?
文法ミスってるのかも
</script>
SVG を出力するテスト
</svg>
code:tsx
const { mount } = await import("./App.tsx");
mount();
code:App.tsx
/** @jsx h */
/** @jsxFrag Fragment */
import {
h,
Fragment,
render,
} from "../preact@10.5.14/mod.js";
import {
useMemo,
useCallback,
} from "../preact@10.5.14/hooks.js";
import { useCodeBlock } from "../PlantUML_live_editor_on_Scrapbox/useCodeBlock.ts";
import { useSVG } from "./useSVG.ts";
interface AppProps {
close: () => void;
}
function App({ close }: AppProps) {
const files = useCodeBlock("svg");
const svgText = useMemo(
() => files0?.lines?.join?.("\n") ?? "", );
const ref = useSVG(svgText);
const onClose = useCallback(() => close(), close); return (
<>
<style>{`
.container {
background-color: var(--page-bg);
border: 1px solid hsl(72, 64%, 57%);
border-radius: 3px;
}
.pin {
position: fixed;
top: 10px;
left: 50%;
transform: translate(-50%, 0);
min-width: 10%;
min-height: 30px;
max-width: 80%;
max-height: 50%;
overflow-y: auto;
z-index: 9999;
}
position: absolute;
top: 0;
right: 0;
}
color: var(--page-text-color, #ccc); }
`}</style>
<div id="preview" className="container pin">
<button id="close" onClick={onClose}>
x
</button>
<div id="svg-container" ref={ref} />
</div>
</>
);
}
export function mount() {
const app = document.createElement("div");
const shadowRoot = app.attachShadow({ mode: "open" });
document.body.append(app);
render(<App close={() => app.remove()} />, shadowRoot);
}
SVGをrenderingする
code:useSVG.ts
import {
useRef,
useEffect,
} from "../preact@10.5.14/hooks.js";
export const useSVG = <E extends HTMLElement>(svgText: string) => {
const ref = useRef<E>(null);
useEffect(() =>{
if (!ref.current) return;
ref.current.textContent = "";
if (svgText === "") return;
const dom = new DOMParser().parseFromString(
svgText,
"image/svg+xml"
);
const error = dom.querySelector("parsererror");
// if failed to parse
if (error) {
ref.current.insertAdjacentHTML(
"beforeend",
dom.documentElement.innerHTML,
);
const pre = document.createElement("pre");
const code = document.createElement("code");
code.innerText = svgText;
pre.append(code);
ref.current.lastElementChild.append(pre);
return;
}
ref.current.append(dom.firstElementChild);
return ref;
};